﻿Shader "Lch/SkyFast"
{
    Properties
    {
		_MoonTex("月亮", 2D) = "white" {}
		_MoonAOInv("弱化AO",Range(0,1)) = 1
        _SkyColor ("天空颜色",Color) = (0.2111516, 0.4499154, 0.6886792,1)
        [HDR]_MinColor ("米氏颜色",Color) = (1, 1, 1,1) 
 
		_MinCtrl2("米氏向上蔓延高度",Range(0.01,1)) = 0
        [HDR]_SunColor("太阳色",Color)=(1., 1., 0.4,1.0)
		_SunRadius("太阳距离",Range(7,50)) = 10
		_SunAlpha("太阳可见度",Range(0,1)) = 1
		_SunEdge("Sun Edge",Range(0.01,0.9)) = 0.001
	    [HDR]_SunRayColor("太阳辉光色",Color)=(0.5, 0.3695906, 0.1533019,1.0)
        _SunRayCtrl("辉光范围",Range(2,512)) = 20
		_ColorColorSun("近太阳云层色",Color) = (1,1,1,1)
		_ColorColor("云层色",Color) = (1,1,1,1)
        _CloudRayColor("云辉光色",Color)=(1., 0.7, 0.2,1.0)
        _CloudTexture ("Cloud Texture", 2D) = "black" {}
	    _CloudSteps ("Cloud Steps", Range(5, 10)) = 10
        _CloudMarchDist ("Cloud March Distance", Range(0.1, 1)) = 0.187
	    _CloudIntensity("_CloudIntensity",Range(0,100)) = 100
        _CloudAmbient ("Cloud Ambient", Range(0, 20)) = 10
	    _CloudArea("_CloudArea",Range(0,1)) = 0.5
        _RotationSpeed("_RotationSpeed",Range(0,0.03)) = 0.01
	    _CloudNoise ("_CloudNoise", 2D) = "black" {}
        _StarPower("_StarPower",Range(0,100)) = 1
		_A("_A 控制对比度",Range(0,4)) = 2.51
		/*_B("_B 调整亮度",Range(0,3)) = 0.03
		_C("_C 控制对比度",Range(0,3)) = 2.43
		_D("_D 控制高光",Range(0,3)) = 0.59*/
		_E("_E 控制低光",Range(0,3)) = 0.14
		_GodRayPower("体积光强度",Range(0,1.0)) = 0
		_BlurStrength("Blur Strength", Range(0, 1)) = 0.05 // 模糊强度
		_BlurSamples("Blur Samples", Range(1, 15)) = 10 // 模糊采样次数
		 _AO("_AO", Range(0, 1)) = 0.05  
        [Toggle(_CUSTOM_LIGHT_ANGLE)]_CUSTOM_LIGHT_ANGLE("自定义光源角度",int) = 0
		[Toggle(GOD_RAY)]GOD_RAY("体积光",int) = 0
		//
		_SunAngle("太阳角度",Range(-10,60) ) = 30
	      [Enum(LEqual, 4, Always, 8 )]
        _ZTest ("深度测试", Float) = 4
		_FogStar("雾开始", Range(1,10000)) = 500
		_FogThickness("雾厚度", Range(1,1000)) = 100
    }
    SubShader
    {
        Tags {   "RenderPipeline" = "UniversalPipeline"  "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }

        Cull Off ZWrite Off 
	 
		
		Pass
        {
			Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency
            ZTest [_ZTest]
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile   _ SKY_FOG_EFFECT
			#pragma multi_compile _ _CUSTOM_LIGHT_ANGLE
			#pragma multi_compile _ GOD_RAY
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
		    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"

            #define UNITY_PI 3.1415926
		    CBUFFER_START(UnityPerMaterial)
      
            float4 _SunColor;
  
			float _SunRadius;
			float _SunAlpha;
			float _SunEdge;
            float4 _SunRayColor;
            float4 _SkyColor;
            float4 _MinColor;
 
			float _MinCtrl2;
            float  _SunRayCtrl;

            float _SunAngle;
            float _CloudSteps;
			float _CloudMarchDist;
			float _CloudAmbient;
			float  _CloudIntensity;
			float _CloudArea;
			float _RotationSpeed;
			float _TestCloud;
			float _CloudDisOffet;
			float _CloudAOPower;
            float4 _CloudRayColor;
			float _BlurStrength;
			float _BlurSamples;
			float _AO;
            float _FogStar;
			float _FogThickness;
			float _ShowScene;
			float4 _ColorColorSun;
			float4 _ColorColor;
			float _MoonAOInv;
			 // 星星的亮度强度
            float _StarPower;
			float _GodRayPower;
			float _A;
			/*float _B;
			float _C;
			float _D;*/
			float _E;
            CBUFFER_END


		    // 云层相关属性
            sampler2D _CloudTexture;
		    sampler2D _CloudNoise;
			sampler2D _MoonTex;
         
            struct Attributes
            {
                float4 positionOS   : POSITION;
            };

            struct Varyings
            {
                float4 positionHCS  : SV_POSITION;
                float3 texcoord : TEXCOORD0;
                float4 ScreenPosition : TEXCOORD1; 
				float3 sunDir : TEXCOORD2; 
				float3 right : TEXCOORD3; 
				float3 up : TEXCOORD4; 

				float4 sunScreenPosition : TEXCOORD5;
				float sun : TEXCOORD6;

            };
            float3 RotateAroundAxis(float3 dir,float3 axis,float angle)
			{
				axis = normalize(axis);
				float cosAngle = cos(angle);
				float sinAngle = sin(angle);
				float oneMinusCos = 1 - cosAngle;
				float xx = axis.x * axis.x;
				float xy = axis.x * axis.y;
				float xz = axis.x * axis.z;
				float yy = axis.y * axis.y;
				float yz = axis.y * axis.z;
				float zz = axis.z * axis.z;
				float3x3 rotationMatrix = float3x3(
					cosAngle + xx * oneMinusCos,
					xy * oneMinusCos - axis.z * sinAngle,
					xz * oneMinusCos + axis.y * sinAngle,

					xy * oneMinusCos + axis.z * sinAngle,
					cosAngle + yy * oneMinusCos,
					yz * oneMinusCos - axis.x * sinAngle,

					xz * oneMinusCos - axis.y * sinAngle,
					yz * oneMinusCos + axis.x * sinAngle,
					cosAngle + zz * oneMinusCos
				);
				return mul(rotationMatrix, dir);
			}


			float3 RotateAroundY(float3 vertex, float alpha)
			{
				float sina, cosa;
				sincos(alpha, sina, cosa);
				float2x2 m = float2x2(cosa, -sina, sina, cosa);
				return float3(mul(m, vertex.xz), vertex.y).xzy;
			}
			float3 RotateAroundYInDegrees(float3 vertex, float degrees)
			{
				float alpha = degrees * UNITY_PI / 180.0;
				float sina, cosa;
				sincos(alpha, sina, cosa);
				float2x2 m = float2x2(cosa, -sina, sina, cosa);
				return float3(mul(m, vertex.xz), vertex.y).xzy;
			}
			float2 DirToMatCapUV(float3 dir, float yScale)
			{
				if (_TestCloud > 0)
				{
					dir = RotateAroundY(dir, _TestCloud);
				}
				else
				{
					dir = RotateAroundY(dir, _Time.y * _RotationSpeed);
				}

				// 保证输入是单位向量
				dir.y *= yScale;              // 压缩 Y 分量，增强平视区域密度
				dir = normalize(dir);
				float2 uv = dir.xz;
				return uv * 0.5 + 0.5;
			}
            Varyings vert(Attributes i)
            {

                Varyings o;
                o.positionHCS = TransformObjectToHClip(i.positionOS.xyz);
                o.texcoord = i.positionOS.xyz;
                o.ScreenPosition = ComputeScreenPos(o.positionHCS );
				#if _CUSTOM_LIGHT_ANGLE
				Light light = GetMainLight( );
				float3 dir0 = light.direction;
				float3 dir1 = normalize( float3(dir0.x,0,dir0.z));
				float3 dir3 = cross(half3(0,-1,0),dir1);
				float3 forward = RotateAroundAxis(dir1,dir3,_SunAngle*UNITY_PI/180.0);
			    o.sunDir = forward;
				#else
				Light light = GetMainLight( );
                float3 forward = light.direction;
				o.sunDir = forward;
				#endif

				if(_GodRayPower>0.01)
				{
					float3 sunPos = o.sunDir * 1000;
					float4 sunHCS =  mul(GetWorldToHClipMatrix(),   float4(sunPos, 1.0));
					o.sunScreenPosition = ComputeScreenPos(sunHCS);
					float4 uvSun;
					uvSun.xy = DirToMatCapUV(o.sunDir, 1.6);
					uvSun.zw = 0;
					float4 uvSun1 = float4(uvSun.x, uvSun.y + 0.01,0,0);
					float4 uvSun2 = float4(uvSun.x, uvSun.y - 0.01,0,0);
					float4 uvSun3 = float4(uvSun.x +0.01 , uvSun.y ,0,0);
					float4 uvSun4 = float4(uvSun.x -0.01 , uvSun.y ,0,0);
					float sun = tex2Dlod(_CloudTexture,uvSun).r
								+ tex2Dlod(_CloudTexture,uvSun1).r
								+ tex2Dlod(_CloudTexture,uvSun2).r
								+ tex2Dlod(_CloudTexture,uvSun3).r
								+ tex2Dlod(_CloudTexture,uvSun4).r
					;
					sun = 1.0-sun*0.5;
					o.sun = sun;
				}
				else
				{
					o.sun = 1.0 ;
				}
				
 

				// 计算右向量
                float3 right = cross(float3(0,1,0), forward);
                float3 up =  cross(forward,right);
				o.right = right;
				o.up = up;

            
                return o;
            }
            static float3 lgt = normalize(float3(0., 0.27, -0.9));
            /*uniform float A  ;  // 控制对比度
		    uniform	float B  ;  // 调整亮度
		    uniform	float C  ;  // 控制对比度
		    uniform	float D  ;  // 控制高光
		    uniform	float E  ;  // 控制低光*/
		    float3 tonemapACES(float3 color)
		    {
			    //float A = 2.51;  // 控制对比度
			    float B = 0.03;  // 调整亮度
			    float C = 2.43;  // 控制对比度
			    float D = 0.59;  // 控制高光
			    //float E = 0.14;  // 控制低光*/

				float A = _A;  // 控制对比度
			    //float B = _B;  // 调整亮度
			    //float C = _C;  // 控制对比度
			    //float D = _D;  // 控制高光
			    float E = _E;  // 控制低光*/

			    // 使用 ACES 映射公式
			    return saturate((color * (A * color + B)) / (color * (C * color + D) + E));
		    }
            
			float3 MatCapUVToDir(float2 uv, float yScale)
			{
				float3 dir;
				dir.xz  = uv.xy * 2 - 1;
				// 计算dir.xz自身的点积
				float dotResult = dot(dir.xz, dir.xz);
				// 确保1.0 - dotResult是非负的
				dir.y = sqrt(max(0.0, 1.0 - dotResult));
				dir.y/=yScale;
			   return normalize( dir) ;
			}
			float clouds(float2 uv)
			{
				return tex2D (_CloudTexture, uv).r;
			}

			static float2 curMatCapUV = 0;
			static float2 sunMatCapUV = 0;
			static float lDotV = 0;
 
			void getClouds2D(in float3 ro, in float3 rd, float scnD, float4 sun, float3 skyCol,inout float3 col)
			{
		
				if(rd.y>0)
				{
					float noise = tex2D(_CloudNoise,float2(rd.x,rd.z  )*10.0 -_Time.y*0.05);
					float2 uv = DirToMatCapUV(rd,1.6);
					curMatCapUV = uv;
					uv+=noise*0.004;
					sunMatCapUV = DirToMatCapUV(lgt,1.6);
					float cloudShape = clouds(uv );
					float2 marchDist = _CloudMarchDist ;
					float stepsInv = 1./_CloudSteps;
					float aoPower = _CloudAmbient/_CloudSteps;
					float2 sunDir = normalize(sunMatCapUV -uv)*marchDist*stepsInv;
					float cloudColor = 1.;
					float2 marchUv = uv;

					UNITY_LOOP
					for (float i = 0.;i<marchDist.x; i += marchDist.x*stepsInv)
					{
						marchUv += sunDir*i;
						float c = clouds(marchUv );
						cloudColor *= clamp(1.-c*aoPower, 0., 1.);
					} 
					cloudColor = exp(-cloudColor)*(1.-exp(-cloudColor*2.))*2.;
					float colt = cloudColor;
					cloudColor *= cloudShape;
					float t2 = smoothstep(_CloudArea,1,lDotV);
					col = skyCol+  lerp(_ColorColor.rgb,_ColorColorSun.rgb,t2)*cloudShape;
					
					col =lerp( col,_SunColor*sun.rgb, (1.-smoothstep(0., 0.4, cloudShape))* sun.a) ;
		 
					float3 cloudCol = _CloudRayColor.rgb*_CloudIntensity * cloudColor  ;
					col = lerp(col,cloudCol , cloudShape*t2);

					//col =lerp( col,_SunColor,   sun) ;
				}
			}
            
			static float3 moonPos = 0;
			static float3 sunRay = 0;
			float4 getSun(float3 rd )
			{

				if( abs(moonPos.x)<1 && abs(moonPos.y)<1)
				{

					float4 c =  tex2D(_MoonTex,moonPos.xy*0.5+0.5)  ;
					c = min(c+_MoonAOInv,1.0);
					
					float dis = sqrt(dot(moonPos.xy,moonPos.xy) );
					float a = smoothstep(1, _SunEdge,dis );
					c.a*=a * _SunAlpha;
					return c ;
			 
					 
				}
				return 0;
	 
			}
			float hash13(float3 p) {
				p = frac(p * 0.3183099 + float3(0.1, 0.1, 0.1));
				p *= 17.0;
				return frac(p.x * p.y * p.z * (p.x + p.y + p.z));
			}

			float hash14(float3 p) {
				p = frac(p * 0.1031);
				p += dot(p, p.yzx + 33.33);
				return frac((p.x + p.y) * p.z);
			}
			float3 hash15(float3 p) {
				p = frac(p * 0.1031);
				p += dot(p, p.yzx + 33.33);
				return frac((p.xxy + p.yzz) * p.zyx);
			}
			void GodRay(inout float4 baseColor, float2 screenPos ,float2 sunPos,float sun)
			{
				if(_GodRayPower>0.01)
				{
					// 计算从当前像素到光源的方向
					float2 uvDir = sunPos.xy - screenPos;
					float2 direction = uvDir;
					float2 dirMC = sunMatCapUV - curMatCapUV;
					float2 dir = normalize(direction);
					// 采样噪声纹理
					half  noise = tex2D(_CloudNoise, dir.xy * 4 + _Time.y).r;
					half  noise2 = tex2D(_CloudNoise, screenPos * 50 + _Time.y).r;
					sunRay = lerp(sunRay, sunRay * noise, 1 - lDotV);

					// 模糊计算相关变量
					float totalWeight = 0;
					float samples = _BlurSamples;
					float strength = _BlurStrength;
					float  rightAndShadow = 0;
					float2 uv1 = screenPos;
					float cloudlight = 0;

					// 权重分布 (高斯分布)
					for (float t = 0; t < samples; t++)
					{
						float scale = (t / samples);
						float weight = 1 - scale;
						float t = (strength + noise2 * 0.01);
						float2 sampleUV = uv1 + uvDir * (strength + noise2 * 0.01) * scale;
						float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, sampleUV);
						float depth01 = Linear01Depth(rawDepth, _ZBufferParams);
						float2 mcUV = curMatCapUV + dirMC * strength *scale;
						float c = 1.0-clouds(mcUV);
						cloudlight += c * weight;
						rightAndShadow += depth01 * weight;
						totalWeight += weight;
					}
 
					rightAndShadow /= totalWeight;
					rightAndShadow = pow(rightAndShadow, 0.45);
					cloudlight /= totalWeight;
					cloudlight = pow(cloudlight,2);
					rightAndShadow *= cloudlight;
					sunRay *= rightAndShadow  ;
					baseColor.rgb = baseColor.rgb*(1 - (1 - rightAndShadow) * lDotV * _AO*sun) + sunRay * sun*_GodRayPower;

 
				}
				
 
			}

			static bool isNoInSky = false;
            float3 render(  in float3 ro, in float3 rd , out float3 bg  )
            {
                float3 col;
                col = _SkyColor.rgb ;
                float rdl = dot(rd, lgt) ;
                float sunDot = max(rdl,0);
				//1.-clamp( rd.y+_MinCtrl2 , 0.,1)
                //米氏
				float mt = clamp(_MinCtrl2- rd.y ,0,1)  ;
                col = lerp(col, _MinColor.rgb,  mt*mt   );
                float4 sun =  getSun(rd  ) ;

				if(_StarPower>0)
				{
					// 星星计算相关
                    half3 pos = rd.xyz *142.8571428571429;
                    half3 center = round(pos);
					float _hash =hash15(center.xyz);
                    if (_hash <0.005 )
                    {
				 
                        // 计算方向向量
                        half3 dir = pos - center;
                        // 计算距离的平方
                        half sqrtDis =  dot(dir,dir);
                        // 计算星星亮度
                        half star =  max(0,0.1 - sqrtDis);
                        // 星星亮度平方
                        star *=star;
                        // 乘以星星强度和哈希值
                        star *= _StarPower   *  _hash*50 ;
                        // 加上时间变化的亮度
                         star *=   1.2+sin(_Time.y*  2   +pos.x+pos.y +pos.z)   ;
						sun += star;
                    } 
				}
  
				#ifdef GOD_RAY
				
				col += sunRay*(1.0-_GodRayPower);
				#else
				col += sunRay * (isNoInSky ?0.3 : 1.0  );
 
				#endif
                bg = col;
                getClouds2D(ro, rd, 10000., sun,  bg,col);
				
                return col;
            }

            half4 frag(Varyings i) : SV_Target
			{

				float2 screenPos = i.ScreenPosition.xy / i.ScreenPosition.w;
				float fogFactor = 1.0;
				
				#if SKY_FOG_EFFECT
				
				float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, screenPos);
				depth = LinearEyeDepth(depth, _ZBufferParams);
				isNoInSky = depth < _ProjectionParams.z * 0.95;
				if (isNoInSky) {

					float factor = depth - _FogStar;
			 
					clip(factor);
					fogFactor = clamp(factor / _FogThickness ,0,1);
				 
				}

				#endif

				float3 ro = 0;
				float3 ray = normalize(i.texcoord);
				lgt = i.sunDir;

				float rdl1 = dot(float3(ray.x, abs(ray.y), ray.z), lgt);
				sunRay = _SunRayColor.rgb * pow(max(rdl1, 0), _SunRayCtrl) * _SunAlpha;

				lDotV = dot(lgt, ray);
				float4x4   moonMat = float4x4(
				i.right,0,
				i.up,0,
				i.sunDir,0,
				0,0,0,1
				);
				moonPos = mul(moonMat,float4(ray * _SunRadius ,1));
				float3 bg;
				float3 atm = render(0,ray,bg);
				float4 fragColor = float4(atm   , 1.);
				
				
				#if SKY_FOG_EFFECT
				if (isNoInSky) {

					fragColor.rgb = bg;
 
				}

				#endif
				
				//fragColor.rgb *=    fogFactor;
				
				
				//#ifdef GOD_RAY
				//GodRay(fragColor, screenPos, i.sunScreenPosition.xy/ i.sunScreenPosition.w,i.sun);
				//#endif
				//fragColor.rgb =  tonemapACES(fragColor.rgb)   ;
				fragColor.a = fogFactor;
	
			
            return fragColor;
            }
            ENDHLSL
        }




		Pass
        {
			Blend One One // Traditional transparency
			Name "GodRay"
			 Tags{"LightMode" = "GodRay"}
           ZTest [_ZTest]
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile   _ SKY_FOG_EFFECT
			#pragma multi_compile _ _CUSTOM_LIGHT_ANGLE
			#pragma multi_compile _ GOD_RAY
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
		    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"

            #define UNITY_PI 3.1415926
		    CBUFFER_START(UnityPerMaterial)
      
            float4 _SunColor;
  
			float _SunRadius;
			float _SunAlpha;
			float _SunEdge;
            float4 _SunRayColor;
            float4 _SkyColor;
            float4 _MinColor;
            float _MinCtrl;
			float _MinCtrl2;
            float  _SunRayCtrl;

            float _SunAngle;
            float _CloudSteps;
			float _CloudMarchDist;
			float _CloudAmbient;
			float  _CloudIntensity;
			float _CloudArea;
			float _RotationSpeed;
			float _TestCloud;
			float _CloudDisOffet;
			float _CloudAOPower;
            float4 _CloudRayColor;
			float _BlurStrength;
			float _BlurSamples;
			float _AO;
            float _FogStar;
			float _FogThickness;
			float _ShowScene;
			float4 _ColorColorSun;
			float4 _ColorColor;
			float _MoonAOInv;
			 // 星星的亮度强度
            float _StarPower;
			float _GodRayPower;
			float _A;
			/*float _B;
			float _C;
			float _D;*/
			float _E;
            CBUFFER_END


		    // 云层相关属性
            sampler2D _CloudTexture;
		    sampler2D _CloudNoise;
			sampler2D _MoonTex;
         
            struct Attributes
            {
                float4 positionOS   : POSITION;
            };

            struct Varyings
            {
                float4 positionHCS  : SV_POSITION;
                float3 texcoord : TEXCOORD0;
                float4 ScreenPosition : TEXCOORD1; 
				float3 sunDir : TEXCOORD2; 
				float3 right : TEXCOORD3; 
				float3 up : TEXCOORD4; 

				float4 sunScreenPosition : TEXCOORD5;
				float sun : TEXCOORD6;

            };
            float3 RotateAroundAxis(float3 dir,float3 axis,float angle)
			{
				axis = normalize(axis);
				float cosAngle = cos(angle);
				float sinAngle = sin(angle);
				float oneMinusCos = 1 - cosAngle;
				float xx = axis.x * axis.x;
				float xy = axis.x * axis.y;
				float xz = axis.x * axis.z;
				float yy = axis.y * axis.y;
				float yz = axis.y * axis.z;
				float zz = axis.z * axis.z;
				float3x3 rotationMatrix = float3x3(
					cosAngle + xx * oneMinusCos,
					xy * oneMinusCos - axis.z * sinAngle,
					xz * oneMinusCos + axis.y * sinAngle,

					xy * oneMinusCos + axis.z * sinAngle,
					cosAngle + yy * oneMinusCos,
					yz * oneMinusCos - axis.x * sinAngle,

					xz * oneMinusCos - axis.y * sinAngle,
					yz * oneMinusCos + axis.x * sinAngle,
					cosAngle + zz * oneMinusCos
				);
				return mul(rotationMatrix, dir);
			}


			float3 RotateAroundY(float3 vertex, float alpha)
			{
				float sina, cosa;
				sincos(alpha, sina, cosa);
				float2x2 m = float2x2(cosa, -sina, sina, cosa);
				return float3(mul(m, vertex.xz), vertex.y).xzy;
			}
			float3 RotateAroundYInDegrees(float3 vertex, float degrees)
			{
				float alpha = degrees * UNITY_PI / 180.0;
				float sina, cosa;
				sincos(alpha, sina, cosa);
				float2x2 m = float2x2(cosa, -sina, sina, cosa);
				return float3(mul(m, vertex.xz), vertex.y).xzy;
			}
			float2 DirToMatCapUV(float3 dir, float yScale)
			{
				if (_TestCloud > 0)
				{
					dir = RotateAroundY(dir, _TestCloud);
				}
				else
				{
					dir = RotateAroundY(dir, _Time.y * _RotationSpeed);
				}

				// 保证输入是单位向量
				dir.y *= yScale;              // 压缩 Y 分量，增强平视区域密度
				dir = normalize(dir);
				float2 uv = dir.xz;
				return uv * 0.5 + 0.5;
			}
            Varyings vert(Attributes i)
            {

                Varyings o;
                o.positionHCS = TransformObjectToHClip(i.positionOS.xyz);
                o.texcoord = i.positionOS.xyz;
                o.ScreenPosition = ComputeScreenPos(o.positionHCS );
				#if _CUSTOM_LIGHT_ANGLE
				Light light = GetMainLight( );
				float3 dir0 = light.direction;
				float3 dir1 = normalize( float3(dir0.x,0,dir0.z));
				float3 dir3 = cross(half3(0,-1,0),dir1);
				float3 forward = RotateAroundAxis(dir1,dir3,_SunAngle*UNITY_PI/180.0);
			    o.sunDir = forward;
				#else
				Light light = GetMainLight( );
                float3 forward = light.direction;
				o.sunDir = forward;
				#endif

				if(_GodRayPower>0.01)
				{
					float3 sunPos = o.sunDir * 1000;
					float4 sunHCS =  mul(GetWorldToHClipMatrix(),   float4(sunPos, 1.0));
					o.sunScreenPosition = ComputeScreenPos(sunHCS);
					float4 uvSun;
					uvSun.xy = DirToMatCapUV(o.sunDir, 1.6);
					uvSun.zw = 0;
					float4 uvSun1 = float4(uvSun.x, uvSun.y + 0.01,0,0);
					float4 uvSun2 = float4(uvSun.x, uvSun.y - 0.01,0,0);
					float4 uvSun3 = float4(uvSun.x +0.01 , uvSun.y ,0,0);
					float4 uvSun4 = float4(uvSun.x -0.01 , uvSun.y ,0,0);
					float sun = tex2Dlod(_CloudTexture,uvSun).r
								+ tex2Dlod(_CloudTexture,uvSun1).r
								+ tex2Dlod(_CloudTexture,uvSun2).r
								+ tex2Dlod(_CloudTexture,uvSun3).r
								+ tex2Dlod(_CloudTexture,uvSun4).r
					;
					sun = 1.0-sun*0.5;
					o.sun = sun;
				}
				else
				{
					o.sun = 1.0 ;
				}
				
 

				// 计算右向量
                float3 right = cross(float3(0,1,0), forward);
                float3 up =  cross(forward,right);
				o.right = right;
				o.up = up;

            
                return o;
            }
            static float3 lgt = normalize(float3(0., 0.27, -0.9));
            /*uniform float A  ;  // 控制对比度
		    uniform	float B  ;  // 调整亮度
		    uniform	float C  ;  // 控制对比度
		    uniform	float D  ;  // 控制高光
		    uniform	float E  ;  // 控制低光*/
		    float3 tonemapACES(float3 color)
		    {
			    //float A = 2.51;  // 控制对比度
			    float B = 0.03;  // 调整亮度
			    float C = 2.43;  // 控制对比度
			    float D = 0.59;  // 控制高光
			    //float E = 0.14;  // 控制低光*/

				float A = _A;  // 控制对比度
			    //float B = _B;  // 调整亮度
			    //float C = _C;  // 控制对比度
			    //float D = _D;  // 控制高光
			    float E = _E;  // 控制低光*/

			    // 使用 ACES 映射公式
			    return saturate((color * (A * color + B)) / (color * (C * color + D) + E));
		    }
            
			float3 MatCapUVToDir(float2 uv, float yScale)
			{
				float3 dir;
				dir.xz  = uv.xy * 2 - 1;
				// 计算dir.xz自身的点积
				float dotResult = dot(dir.xz, dir.xz);
				// 确保1.0 - dotResult是非负的
				dir.y = sqrt(max(0.0, 1.0 - dotResult));
				dir.y/=yScale;
			   return normalize( dir) ;
			}
			float clouds(float2 uv)
			{
				return tex2D (_CloudTexture, uv).r;
			}

			static float2 curMatCapUV = 0;
			static float2 sunMatCapUV = 0;
			static float lDotV = 0;
 
			 
            
		 
			static float3 sunRay = 0;
		 
		 
			void GodRay(inout float4 baseColor, float2 screenPos ,float2 sunPos,float sun)
			{
				if(_GodRayPower>0.01)
				{
					// 计算从当前像素到光源的方向
					float2 uvDir = sunPos.xy - screenPos;
					float2 direction = uvDir;
					float2 dirMC = sunMatCapUV - curMatCapUV;
					float2 dir = normalize(direction);
					// 采样噪声纹理
					half  noise = tex2D(_CloudNoise, dir.xy * 4 + _Time.y).r;
					half  noise2 = tex2D(_CloudNoise, screenPos * 50 + _Time.y).r;
					sunRay = lerp(sunRay, sunRay * noise, 1 - lDotV);

					// 模糊计算相关变量
					float totalWeight = 0;
					float samples = _BlurSamples;
					float strength = _BlurStrength;
					float  rightAndShadow = 0;
					float2 uv1 = screenPos;
					float cloudlight = 0;

					// 权重分布 (高斯分布)
					for (float t = 0; t < samples; t++)
					{
						float scale = (t / samples);
						float weight = 1 - scale;
						float t = (strength + noise2 * 0.01);
						float2 sampleUV = uv1 + uvDir * (strength + noise2 * 0.01) * scale;
						float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, sampleUV);
						float depth01 = Linear01Depth(rawDepth, _ZBufferParams);
						float2 mcUV = curMatCapUV + dirMC * strength *scale;
						float c = 1.0-clouds(mcUV);
						cloudlight += c * weight;
						rightAndShadow += depth01 * weight;
						totalWeight += weight;
					}
 
					rightAndShadow /= totalWeight;
					rightAndShadow = pow(rightAndShadow, 0.45);
					cloudlight /= totalWeight;
					cloudlight = pow(cloudlight,2);
					rightAndShadow *= cloudlight;
					sunRay *= rightAndShadow  ;
					baseColor.rgb = baseColor.rgb*(1 - (1 - rightAndShadow) * lDotV * _AO*sun) + sunRay * sun*_GodRayPower;

 
				}
				
 
			}
            

            half4 frag(Varyings i) : SV_Target
			{
				float3 ro = 0;
				float3 ray = normalize(i.texcoord);
				lgt = i.sunDir;

				float rdl1 = dot(float3(ray.x, abs(ray.y), ray.z), lgt);
				sunRay = _SunRayColor.rgb * pow(max(rdl1, 0), _SunRayCtrl) * _SunAlpha;

				lDotV = dot(lgt, ray);
		 
	 
			 
				float4 fragColor = float4(0,0,0, 1.);

				float2 screenPos = i.ScreenPosition.xy / i.ScreenPosition.w;
				 
				
				
				#ifdef GOD_RAY
				GodRay(fragColor, screenPos, i.sunScreenPosition.xy/ i.sunScreenPosition.w,i.sun);
			    fragColor.rgb =  tonemapACES(fragColor.rgb)   ;
				#endif

				 
	
			
            return fragColor;
            }
            ENDHLSL
        }
    }
}